home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / prog / dflt18.arj / HELPBOX.C < prev    next >
Text File  |  1994-03-24  |  19KB  |  621 lines

  1. /* ------------ helpbox.c ----------- */
  2.  
  3. #include "dflat.h"
  4. #include "htree.h"
  5.  
  6. extern DBOX HelpBox;
  7.  
  8. /* -------- strings of D-Flat classes for calling default
  9.       help text collections -------- */
  10. char *ClassNames[] = {
  11.     #undef ClassDef
  12.     #define ClassDef(c,b,p,a) #c,
  13.     #include "classes.h"
  14.     NULL
  15. };
  16.  
  17. #define MAXHEIGHT (SCREENHEIGHT-10)
  18. #define MAXHELPKEYWORDS 50  /* --- maximum keywords in a window --- */
  19. #define MAXHELPSTACK 100
  20.  
  21. static struct helps *FirstHelp;
  22. static struct helps *ThisHelp;
  23. static int HelpCount;
  24.  
  25. static int HelpStack[MAXHELPSTACK];
  26. static int stacked;
  27.  
  28. /* --- keywords in the current help text -------- */
  29. static struct keywords {
  30.     struct helps *hkey;
  31.     int lineno;
  32.     int off1, off2, off3;
  33.     char isDefinition;
  34. } KeyWords[MAXHELPKEYWORDS];
  35. static struct keywords *thisword;
  36. static int keywordcount;
  37.  
  38. static FILE *helpfp;
  39. static char hline [160];
  40. static BOOL Helping;
  41.  
  42. static void SelectHelp(WINDOW, struct helps *, BOOL);
  43. static void ReadHelp(WINDOW);
  44. static struct helps *FindHelp(char *);
  45. static void DisplayDefinition(WINDOW, char *);
  46. static void BestFit(WINDOW, DIALOGWINDOW *);
  47.  
  48. /* ------------- CREATE_WINDOW message ------------ */
  49. static void CreateWindowMsg(WINDOW wnd)
  50. {
  51.     Helping = TRUE;
  52.     GetClass(wnd) = HELPBOX;
  53.     InitWindowColors(wnd);
  54.     if (ThisHelp != NULL)
  55.         ThisHelp->hwnd = wnd;
  56. }
  57.  
  58. /* ------------- COMMAND message ------------ */
  59. static BOOL CommandMsg(WINDOW wnd, PARAM p1)
  60. {
  61.     switch ((int)p1)    {
  62.         case ID_PREV:
  63.             if (ThisHelp  != NULL)
  64.                 SelectHelp(wnd, FirstHelp+(ThisHelp->prevhlp), TRUE);
  65.             return TRUE;
  66.         case ID_NEXT:
  67.             if (ThisHelp != NULL)
  68.                 SelectHelp(wnd, FirstHelp+(ThisHelp->nexthlp), TRUE);
  69.             return TRUE;
  70.         case ID_BACK:
  71.             if (stacked)
  72.                 SelectHelp(wnd, FirstHelp+HelpStack[--stacked], FALSE);
  73.             return TRUE;
  74.         default:
  75.             break;
  76.     }
  77.     return FALSE;
  78. }
  79.  
  80. /* ------------- KEYBOARD message ------------ */
  81. static BOOL KeyboardMsg(WINDOW wnd, PARAM p1)
  82. {
  83.     WINDOW cwnd;
  84.  
  85.     cwnd = ControlWindow(wnd->extension, ID_HELPTEXT);
  86.     if (cwnd == NULL || inFocus != cwnd)
  87.         return FALSE;
  88.     switch ((int)p1)    {
  89.         case '\r':
  90.             if (keywordcount)
  91.                 if (thisword != NULL)    {
  92.                     char *hp = thisword->hkey->hname;
  93.                     if (thisword->isDefinition)
  94.                         DisplayDefinition(GetParent(wnd), hp);
  95.                     else
  96.                         SelectHelp(wnd, thisword->hkey, TRUE);
  97.                 }
  98.             return TRUE;
  99.         case '\t':
  100.             if (!keywordcount)
  101.                 return TRUE;
  102.             if (thisword == NULL ||
  103.                     ++thisword == KeyWords+keywordcount)
  104.                 thisword = KeyWords;
  105.             break;
  106.         case SHIFT_HT:
  107.             if (!keywordcount)
  108.                 return TRUE;
  109.             if (thisword == NULL || thisword == KeyWords)
  110.                 thisword = KeyWords+keywordcount;
  111.             --thisword;
  112.             break;;
  113.         default:
  114.             return FALSE;
  115.     }
  116.     if (thisword->lineno < cwnd->wtop ||
  117.             thisword->lineno >=
  118.                 cwnd->wtop + ClientHeight(cwnd))  {
  119.         int distance = ClientHeight(cwnd)/2;
  120.         do    {
  121.             cwnd->wtop = thisword->lineno-distance;
  122.             distance /= 2;
  123.         }
  124.         while (cwnd->wtop < 0);
  125.     }
  126.     SendMessage(cwnd, PAINT, 0, 0);
  127.     return TRUE;
  128. }
  129.  
  130. /* ---- window processing module for the HELPBOX ------- */
  131. int HelpBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  132. {
  133.     switch (msg)    {
  134.         case CREATE_WINDOW:
  135.             CreateWindowMsg(wnd);
  136.             break;
  137.         case INITIATE_DIALOG:
  138.             ReadHelp(wnd);
  139.             break;
  140.         case COMMAND:
  141.             if (p2 != 0)
  142.                 break;
  143.             if (CommandMsg(wnd, p1))
  144.                 return TRUE;
  145.             break;
  146.         case KEYBOARD:
  147.             if (WindowMoving)
  148.                 break;
  149.             if (KeyboardMsg(wnd, p1))
  150.                 return TRUE;
  151.             break;
  152.         case CLOSE_WINDOW:
  153.             if (ThisHelp != NULL)
  154.                 ThisHelp->hwnd = NULL;
  155.             Helping = FALSE;
  156.             break;
  157.         default:
  158.             break;
  159.     }
  160.     return BaseWndProc(HELPBOX, wnd, msg, p1, p2);
  161. }
  162.  
  163. /* ---- PAINT message for the helpbox text editbox ---- */
  164. static int PaintMsg(WINDOW wnd, PARAM p1, PARAM p2)
  165. {
  166.     int rtn;
  167.     if (thisword != NULL)    {
  168.         WINDOW pwnd = GetParent(wnd);
  169.         char *cp;
  170.         cp = TextLine(wnd, thisword->lineno);
  171.         cp += thisword->off1;
  172.         *(cp+1) =
  173.             (pwnd->WindowColors[SELECT_COLOR][FG] & 255) | 0x80;
  174.         *(cp+2) =
  175.             (pwnd->WindowColors[SELECT_COLOR][BG] & 255) | 0x80;
  176.         rtn = DefaultWndProc(wnd, PAINT, p1, p2);
  177.         *(cp+1) =
  178.             (pwnd->WindowColors[HILITE_COLOR][FG] & 255) | 0x80;
  179.         *(cp+2) =
  180.             (pwnd->WindowColors[HILITE_COLOR][BG] & 255) | 0x80;
  181.         return rtn;
  182.     }
  183.     return DefaultWndProc(wnd, PAINT, p1, p2);
  184. }
  185.  
  186. /* ---- LEFT_BUTTON message for the helpbox text editbox ---- */
  187. static int LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2)
  188. {
  189.     int rtn, mx, my, i;
  190.  
  191.     rtn = DefaultWndProc(wnd, LEFT_BUTTON, p1, p2);
  192.     mx = (int)p1 - GetClientLeft(wnd);
  193.     my = (int)p2 - GetClientTop(wnd);
  194.     my += wnd->wtop;
  195.     thisword = KeyWords;
  196.     for (i = 0; i < keywordcount; i++)    {
  197.         if (my == thisword->lineno)    {
  198.             if (mx >= thisword->off2 &&
  199.                         mx < thisword->off3)    {
  200.                 SendMessage(wnd, PAINT, 0, 0);
  201.                 if (thisword->isDefinition)    {
  202.                     WINDOW pwnd = GetParent(wnd);
  203.                     if (pwnd != NULL)
  204.                         DisplayDefinition(GetParent(pwnd),
  205.                             thisword->hkey->hname);
  206.                 }
  207.                 break;
  208.             }
  209.         }
  210.         thisword++;
  211.     }
  212.     if (i == keywordcount)
  213.         thisword = NULL;
  214.     return rtn;
  215. }
  216.  
  217. /* --- window processing module for HELPBOX's text EDITBOX -- */
  218. int HelpTextProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  219. {
  220.     switch (msg)    {
  221.         case KEYBOARD:
  222.             break;
  223.         case PAINT:
  224.             return PaintMsg(wnd, p1, p2);
  225.         case LEFT_BUTTON:
  226.             return LeftButtonMsg(wnd, p1, p2);
  227.         case DOUBLE_CLICK:
  228.             PostMessage(wnd, KEYBOARD, '\r', 0);
  229.             break;
  230.         default:
  231.             break;
  232.     }
  233.     return DefaultWndProc(wnd, msg, p1, p2);
  234. }
  235.  
  236. /* -------- read the help text into the editbox ------- */
  237. static void ReadHelp(WINDOW wnd)
  238. {
  239.     WINDOW cwnd = ControlWindow(wnd->extension, ID_HELPTEXT);
  240.     int linectr = 0;
  241.     if (cwnd == NULL)
  242.         return;
  243.     thisword = KeyWords;
  244.     keywordcount = 0;
  245.     cwnd->wndproc = HelpTextProc;
  246.     SendMessage(cwnd, CLEARTEXT, 0, 0);
  247.     /* ----- read the help text ------- */
  248.     while (TRUE)    {
  249.         unsigned char *cp = hline, *cp1;
  250.         int colorct = 0;
  251.         if (GetHelpLine(hline) == NULL)
  252.             break;
  253.         if (*hline == '<')
  254.             break;
  255.         hline[strlen(hline)-1] = '\0';
  256.         /* --- add help text to the help window --- */
  257.         while (cp != NULL)    {
  258.             if ((cp = strchr(cp, '[')) != NULL)    {
  259.                 /* ----- hit a new key word ----- */
  260.                 if (*(cp+1) != '.' && *(cp+1) != '*')    {
  261.                     cp++;
  262.                     continue;
  263.                 }
  264.                 thisword->lineno = cwnd->wlines;
  265.                 thisword->off1 = (int) (cp - hline);
  266.                 thisword->off2 = thisword->off1 - colorct * 4;
  267.                 thisword->isDefinition = *(cp+1) == '*';
  268.                 colorct++;
  269.                 *cp++ = CHANGECOLOR;
  270.                 *cp++ =
  271.             (wnd->WindowColors [HILITE_COLOR] [FG] & 255) | 0x80;
  272.                 *cp++ =
  273.             (wnd->WindowColors [HILITE_COLOR] [BG] & 255) | 0x80;
  274.                 cp1 = cp;
  275.                 if ((cp = strchr(cp, ']')) != NULL)    {
  276.                     if (thisword != NULL)
  277.                         thisword->off3 =
  278.                             thisword->off2 + (int) (cp - cp1);
  279.                     *cp++ = RESETCOLOR;
  280.                 }
  281.                 if ((cp = strchr(cp, '<')) != NULL)    {
  282.                     char *cp1 = strchr(cp, '>');
  283.                     if (cp1 != NULL)    {
  284.                         char hname[80];
  285.                         int len = (int) (cp1 - cp);
  286.                         memset(hname, 0, 80);
  287.                         strncpy(hname, cp+1, len-1);
  288.                         thisword->hkey = FindHelp(hname);
  289.                         memmove(cp, cp1+1, strlen(cp1));
  290.                     }
  291.                 }
  292.                 thisword++;
  293.                 keywordcount++;
  294.             }
  295.         }
  296.         PutItemText(wnd, ID_HELPTEXT, hline);
  297.         /* -- display help text as soon as window is full -- */
  298.         if (++linectr == ClientHeight(cwnd))    {
  299.             struct keywords *holdthis = thisword;
  300.             thisword = NULL;
  301.             SendMessage(cwnd, PAINT, 0, 0);
  302.             thisword = holdthis;
  303.         }
  304.         if (linectr > ClientHeight(cwnd) &&
  305.                 !TestAttribute(cwnd, VSCROLLBAR))    {
  306.             AddAttribute(cwnd, VSCROLLBAR);
  307.             SendMessage(cwnd, BORDER, 0, 0);
  308.         }
  309.     }
  310.     thisword = NULL;
  311. }
  312.  
  313. /* ---- compute the displayed length of a help text line --- */
  314. static int HelpLength(char *s)
  315. {
  316.     int len = strlen(s);
  317.     char *cp = strchr(s, '[');
  318.     while (cp != NULL)    {
  319.         len -= 4;
  320.         cp = strchr(cp+1, '[');
  321.     }
  322.     cp = strchr(s, '<');
  323.     while (cp != NULL)    {
  324.         char *cp1 = strchr(cp, '>');
  325.         if (cp1 != NULL)
  326.             len -= (int) (cp1-cp)+1;
  327.         cp = strchr(cp1, '<');
  328.     }
  329.     return len;
  330. }
  331.  
  332. /* ----------- load the help text file ------------ */
  333. void LoadHelpFile()
  334. {
  335.     long where;
  336.     int i;
  337.     if (Helping)
  338.         return;
  339.     UnLoadHelpFile();
  340.     if ((helpfp = OpenHelpFile()) == NULL)
  341.         return;
  342.     fseek(helpfp, - (long) sizeof(long), SEEK_END);
  343.     fread(&where, sizeof(long), 1, helpfp);
  344.     fseek(helpfp, where, SEEK_SET);
  345.     fread(&HelpCount, sizeof(int), 1, helpfp);
  346.     FirstHelp = DFcalloc(sizeof(struct helps) * HelpCount, 1);
  347.     for (i = 0; i < HelpCount; i++)    {
  348.         int len;
  349.         fread(&len, sizeof(int), 1, helpfp);
  350.         if (len)    {
  351.             (FirstHelp+i)->hname = DFcalloc(len+1, 1);
  352.             fread((FirstHelp+i)->hname, len+1, 1, helpfp);
  353.         }
  354.         fread(&len, sizeof(int), 1, helpfp);
  355.         if (len)    {
  356.             (FirstHelp+i)->comment = DFcalloc(len+1, 1);
  357.             fread((FirstHelp+i)->comment, len+1, 1, helpfp);
  358.         }
  359.         fread(&(FirstHelp+i)->hptr, sizeof(int)*5+sizeof(long), 1, helpfp);
  360.     }
  361.     fclose(helpfp);
  362. }
  363.  
  364. /* ------ free the memory used by the help file table ------ */
  365. void UnLoadHelpFile(void)
  366. {
  367.     int i;
  368.     for (i = 0; i < HelpCount; i++)    {
  369.         free((FirstHelp+i)->comment);
  370.         free((FirstHelp+i)->hname);
  371.     }
  372.     free(FirstHelp);
  373.     FirstHelp = NULL;
  374.     free(HelpTree);
  375.     HelpTree = NULL;
  376. }
  377.  
  378. static void BuildHelpBox(WINDOW wnd)
  379. {
  380.     int offset, i;
  381.  
  382.     /* -- seek to the first line of the help text -- */
  383.     SeekHelpLine(ThisHelp->hptr, ThisHelp->bit);
  384.     /* ----- read the title ----- */
  385.     GetHelpLine(hline);
  386.     hline[strlen(hline)-1] = '\0';
  387.     free(HelpBox.dwnd.title);
  388.     HelpBox.dwnd.title = DFmalloc(strlen(hline)+1);
  389.     strcpy(HelpBox.dwnd.title, hline);
  390.     /* ----- set the height and width ----- */
  391.     HelpBox.dwnd.h = min(ThisHelp->hheight, MAXHEIGHT)+7;
  392.     HelpBox.dwnd.w = max(45, ThisHelp->hwidth+6);
  393.     /* ------ position the help window ----- */
  394.     if (wnd != NULL)
  395.         BestFit(wnd, &HelpBox.dwnd);
  396.     /* ------- position the command buttons ------ */
  397.     HelpBox.ctl[0].dwnd.w = max(40, ThisHelp->hwidth+2);
  398.     HelpBox.ctl[0].dwnd.h =
  399.                 min(ThisHelp->hheight, MAXHEIGHT)+2;
  400.     offset = (HelpBox.dwnd.w-40) / 2;
  401.     for (i = 1; i < 5; i++)    {
  402.            HelpBox.ctl[i].dwnd.y =
  403.                    min(ThisHelp->hheight, MAXHEIGHT)+3;
  404.            HelpBox.ctl[i].dwnd.x = (i-1) * 10 + offset;
  405.     }
  406.     /* ---- disable ineffective buttons ---- */
  407.     if (ThisHelp->nexthlp == -1)
  408.         DisableButton(&HelpBox, ID_NEXT);
  409.     else
  410.         EnableButton(&HelpBox, ID_NEXT);
  411.     if (ThisHelp->prevhlp == -1)
  412.         DisableButton(&HelpBox, ID_PREV);
  413.     else 
  414.         EnableButton(&HelpBox, ID_PREV);
  415. }
  416.  
  417. /* ----- select a new help window from its name ----- */
  418. static void SelectHelp(WINDOW wnd, struct helps *newhelp, BOOL recall)
  419. {
  420.     if (newhelp != NULL)    {
  421.         int i, x, y;
  422.         SendMessage(wnd, HIDE_WINDOW, 0, 0);
  423.         if (recall && stacked < MAXHELPSTACK)
  424.             HelpStack[stacked++] = ThisHelp-FirstHelp;
  425.         ThisHelp = newhelp;
  426.         SendMessage(GetParent(wnd), DISPLAY_HELP, (PARAM) ThisHelp->hname, 0);
  427.         if (stacked)
  428.             EnableButton(&HelpBox, ID_BACK);
  429.         else 
  430.             DisableButton(&HelpBox, ID_BACK);
  431.         BuildHelpBox(NULL);
  432.         AddTitle(wnd, HelpBox.dwnd.title);
  433.         /* --- reposition and resize the help window --- */
  434.         HelpBox.dwnd.x = (SCREENWIDTH-HelpBox.dwnd.w)/2;
  435.         HelpBox.dwnd.y = (SCREENHEIGHT-HelpBox.dwnd.h)/2;
  436.         SendMessage(wnd, MOVE, HelpBox.dwnd.x, HelpBox.dwnd.y);
  437.         SendMessage(wnd, SIZE,
  438.                         HelpBox.dwnd.x + HelpBox.dwnd.w - 1,
  439.                         HelpBox.dwnd.y + HelpBox.dwnd.h - 1);
  440.         /* --- reposition the controls --- */
  441.         for (i = 0; i < 5; i++)    {
  442.             WINDOW cwnd = HelpBox.ctl[i].wnd;
  443.             x = HelpBox.ctl[i].dwnd.x+GetClientLeft(wnd);
  444.             y = HelpBox.ctl[i].dwnd.y+GetClientTop(wnd);
  445.             SendMessage(cwnd, MOVE, x, y);
  446.             if (i == 0)    {
  447.                 x += HelpBox.ctl[i].dwnd.w - 1;
  448.                 y += HelpBox.ctl[i].dwnd.h - 1;
  449.                 SendMessage(cwnd, SIZE, x, y);
  450.             }
  451.         }
  452.         /* --- read the help text into the help window --- */
  453.         ReadHelp(wnd);
  454.         SendMessage(wnd, SHOW_WINDOW, 0, 0);
  455.     }
  456. }
  457. /* ---- strip tildes from the help name ---- */
  458. static void StripTildes(char *fh, char *hp)
  459. {
  460.     while (*hp)    {
  461.         if (*hp != '~')
  462.             *fh++ = *hp;
  463.         hp++;
  464.     }
  465.     *fh = '\0';
  466. }
  467. /* --- return the comment associated with a help window --- */
  468. char *HelpComment(char *Help)
  469. {
  470.     char FixedHelp[30];
  471.     StripTildes(FixedHelp, Help);
  472.     if ((ThisHelp = FindHelp(FixedHelp)) != NULL)
  473.         return ThisHelp->comment;
  474.     return NULL;
  475. }
  476. /* ---------- display help text ----------- */
  477. BOOL DisplayHelp(WINDOW wnd, char *Help)
  478. {
  479.     char FixedHelp[30];
  480.     BOOL rtn = FALSE;
  481.  
  482.     if (Helping)
  483.         return TRUE;
  484.     StripTildes(FixedHelp, Help);
  485.     stacked = 0;
  486.     wnd->isHelping++;
  487.     if ((ThisHelp = FindHelp(FixedHelp)) != NULL)    {
  488.         if ((helpfp = OpenHelpFile()) != NULL)    {
  489.             BuildHelpBox(wnd);
  490.             DisableButton(&HelpBox, ID_BACK);
  491.             /* ------- display the help window ----- */
  492.             DialogBox(NULL, &HelpBox, TRUE, HelpBoxProc);
  493.             free(HelpBox.dwnd.title);
  494.             HelpBox.dwnd.title = NULL;
  495.             fclose(helpfp);
  496.             rtn = TRUE;
  497.         }
  498.     }
  499.     --wnd->isHelping;
  500.     return rtn;
  501. }
  502.  
  503. /* ------- display a definition window --------- */
  504. static void DisplayDefinition(WINDOW wnd, char *def)
  505. {
  506.     WINDOW dwnd;
  507.     WINDOW hwnd = wnd;
  508.     int y;
  509.  
  510.     if (GetClass(wnd) == POPDOWNMENU)
  511.         hwnd = GetParent(wnd);
  512.     y = GetClass(hwnd) == MENUBAR ? 2 : 1;
  513.     if ((ThisHelp = FindHelp(def)) != NULL)    {
  514.         clearBIOSbuffer();
  515.         if ((helpfp = OpenHelpFile()) != NULL)    {
  516.             clearBIOSbuffer();
  517.             dwnd = CreateWindow(
  518.                         TEXTBOX,
  519.                         NULL,
  520.                         GetClientLeft(hwnd),
  521.                         GetClientTop(hwnd)+y,
  522.                         min(ThisHelp->hheight, MAXHEIGHT)+3,
  523.                         ThisHelp->hwidth+2,
  524.                         NULL,
  525.                         wnd,
  526.                         NULL,
  527.                         HASBORDER | NOCLIP | SAVESELF);
  528.             if (dwnd != NULL)    {
  529.                 clearBIOSbuffer();
  530.                 /* ----- read the help text ------- */
  531.                 SeekHelpLine(ThisHelp->hptr, ThisHelp->bit);
  532.                 while (TRUE)    {
  533.                     clearBIOSbuffer();
  534.                     if (GetHelpLine(hline) == NULL)
  535.                         break;
  536.                     if (*hline == '<')
  537.                         break;
  538.                     hline[strlen(hline)-1] = '\0';
  539.                     SendMessage(dwnd,ADDTEXT,(PARAM)hline,0);
  540.                 }
  541.                 SendMessage(dwnd, SHOW_WINDOW, 0, 0);
  542.                 SendMessage(NULL, WAITKEYBOARD, 0, 0);
  543.                 SendMessage(NULL, WAITMOUSE, 0, 0);
  544.                 SendMessage(dwnd, CLOSE_WINDOW, 0, 0);
  545.             }
  546.             fclose(helpfp);
  547.         }
  548.     }
  549. }
  550.  
  551. /* ------ compare help names with wild cards ----- */
  552. static BOOL wildcmp(char *s1, char *s2)
  553. {
  554.     while (*s1 || *s2)    {
  555.         if (tolower(*s1) != tolower(*s2))
  556.             if (*s1 != '?' && *s2 != '?')
  557.                 return TRUE;
  558.         s1++, s2++;
  559.     }
  560.     return FALSE;
  561. }
  562.  
  563. /* --- ThisHelp = the help window matching specified name --- */
  564. static struct helps *FindHelp(char *Help)
  565. {
  566.     int i;
  567.     struct helps *thishelp = NULL;
  568.     for (i = 0; i < HelpCount; i++)    {
  569.         if (wildcmp(Help, (FirstHelp+i)->hname) == FALSE)    {
  570.             thishelp = FirstHelp+i;
  571.             break;
  572.         }
  573.     }
  574.     return thishelp;
  575. }
  576.  
  577. static int OverLap(int a, int b)
  578. {
  579.     int ov = a - b;
  580.     if (ov < 0)
  581.         ov = 0;
  582.     return ov;
  583. }
  584.  
  585. /* ----- compute the best location for a help dialogbox ----- */
  586. static void BestFit(WINDOW wnd, DIALOGWINDOW *dwnd)
  587. {
  588.     int above, below, right, left;
  589.     if (GetClass(wnd) == MENUBAR ||
  590.                 GetClass(wnd) == APPLICATION)    {
  591.         dwnd->x = dwnd->y = -1;
  592.         return;
  593.     }
  594.     /* --- compute above overlap ---- */
  595.     above = OverLap(dwnd->h, GetTop(wnd));
  596.     /* --- compute below overlap ---- */
  597.     below = OverLap(GetBottom(wnd), SCREENHEIGHT-dwnd->h);
  598.     /* --- compute right overlap ---- */
  599.     right = OverLap(GetRight(wnd), SCREENWIDTH-dwnd->w);
  600.     /* --- compute left  overlap ---- */
  601.     left = OverLap(dwnd->w, GetLeft(wnd));
  602.  
  603.     if (above < below)
  604.         dwnd->y = max(0, GetTop(wnd)-dwnd->h-2);
  605.     else
  606.         dwnd->y = min(SCREENHEIGHT-dwnd->h, GetBottom(wnd)+2);
  607.     if (right < left)
  608.         dwnd->x = min(GetRight(wnd)+2, SCREENWIDTH-dwnd->w);
  609.     else
  610.         dwnd->x = max(0, GetLeft(wnd)-dwnd->w-2);
  611.  
  612.     if (dwnd->x == GetRight(wnd)+2 ||
  613.             dwnd->x == GetLeft(wnd)-dwnd->w-2)
  614.         dwnd->y = -1;
  615.     if (dwnd->y ==GetTop(wnd)-dwnd->h-2 ||
  616.             dwnd->y == GetBottom(wnd)+2)
  617.         dwnd->x = -1;
  618. }
  619.  
  620. 
  621.